﻿using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace TestPrint.XMLhelp
{
    public class XmlSerializerHelper
    {
        #region Xml系列化
        public static void Serialize<T>(Stream stream, T instance)
        {
            Serialize<T>(stream, instance, null, null, true);
        }

        public static void Serialize<T>(Stream stream, T instance, Encoding encoding)
        {
            Serialize<T>(stream, instance, null, encoding, true);
        }
        public static void Serialize<T>(Stream stream, T instance, XmlSerializerNamespaces ns, bool CloseStream = true)
        {
            if (instance == null) return;
            XmlSerializer xs = new XmlSerializer(typeof(T));
            if (ns == null)
                xs.Serialize(stream, instance);
            else
                xs.Serialize(stream, instance, ns);

            if (CloseStream)
            {
                stream.Close();
            }
        }
        public static void Serialize<T>(Stream stream, T instance, XmlSerializerNamespaces ns, Encoding encoding, bool CloseStream = true)
        {
            if (instance == null) return;
            XmlSerializer xs = new XmlSerializer(typeof(T));

            StreamWriter writer = null;
            if (encoding == null)
                writer = new StreamWriter(stream);
            else
                writer = new StreamWriter(stream, encoding);

            if (ns == null)
                xs.Serialize(writer, instance);
            else
                xs.Serialize(writer, instance, ns);
            if (CloseStream)
            {
                writer.Close();
                stream.Close();
            }
        }
        public static MemoryStream Serialize<T>(T instance)
        {
            return Serialize<T>(instance, null, null);
        }
        public static MemoryStream Serialize<T>(T instance, Encoding encoding)
        {
            return Serialize<T>(instance, null, encoding);
        }
        public static MemoryStream Serialize<T>(T instance, XmlSerializerNamespaces ns)
        {
            if (instance == null) return null;
            MemoryStream ms = new MemoryStream();
            Serialize<T>(ms, instance, ns, false);
            return ms;
        }
        public static MemoryStream Serialize<T>(T instance, XmlSerializerNamespaces ns, Encoding encoding)
        {
            if (instance == null) return null;
            MemoryStream ms = new MemoryStream();
            Serialize<T>(ms, instance, ns, encoding, false);
            return ms;
        }
        public static string SerializeToString<T>(T instance)
        {
            return SerializeToString<T>(instance, null, Encoding.UTF8);
        }
        public static string SerializeToString<T>(T instance, Encoding encoding)
        {
            return SerializeToString<T>(instance, null, encoding);
        }

        public static string SerializeToString<T>(T instance, XmlSerializerNamespaces ns)
        {
            return SerializeToString<T>(instance, ns, Encoding.UTF8);
        }

        public static string SerializeToString<T>(T instance, XmlSerializerNamespaces ns, Encoding encoding)
        {
            using (MemoryStream ms = Serialize(instance, ns, encoding))
            {
                ms.Position = 0;
                using (StreamReader sr = new StreamReader(ms, encoding))
                {
                    return sr.ReadToEnd();
                }
            }
        }

        public static byte[] SerializeToBytes<T>(T instance)
        {
            return SerializeToBytes<T>(instance, null, null);
        }
        public static byte[] SerializeToBytes<T>(T instance, Encoding encoding)
        {
            return SerializeToBytes<T>(instance, null, null);
        }
        public static byte[] SerializeToBytes<T>(T instance, XmlSerializerNamespaces ns)
        {
            using (MemoryStream ms = Serialize<T>(instance, ns))
            {
                return ms.ToArray();
            }
        }
        public static byte[] SerializeToBytes<T>(T instance, XmlSerializerNamespaces ns, Encoding encoding)
        {
            using (MemoryStream ms = Serialize<T>(instance, ns, encoding))
            {
                return ms.ToArray();
            }
        }
        #endregion

        #region xml反系列化

        /// <summary>
        /// XML反系列化
        /// </summary>
        /// <param name="ms">Stream流</param>
        public static T DeSerialize<T>(Stream ms, Encoding encoding = null)
        {
            if (encoding == null) encoding = Encoding.UTF8;
            ms.Position = 0;
            using (StreamReader sr = new StreamReader(ms, encoding))
            {
                //通过XmlReader.Create静态方法创建XmlReader实例  
                using (XmlReader rdr = XmlReader.Create(sr))
                {
                    XmlSerializer xs = new XmlSerializer(typeof(T));
                    T model = (T)xs.Deserialize(rdr);
                    return model;
                }
            }
        }

        /// <summary>
        /// XML反系列化
        /// </summary>
        /// <param name="str">xml字符串</param>
        public static T DeSerializeString<T>(string str, Encoding encoding = null)
        {
            if (encoding == null) encoding = Encoding.UTF8;
            using (MemoryStream ms = new MemoryStream())
            {
                byte[] bytes = encoding.GetBytes(str);
                BinaryWriter bw = new BinaryWriter(ms);
                bw.Write(bytes);
                return DeSerialize<T>(ms);
            }
        }

        /// <summary>
        /// XML反系列化
        /// </summary>
        /// <param name="bytes">字节数组</param>
        public static T DeSerializeBytes<T>(byte[] bytes, Encoding encoding = null)
        {
            if (encoding == null) encoding = Encoding.UTF8;
            using (MemoryStream ms = new MemoryStream())
            {
                BinaryWriter bw = new BinaryWriter(ms);
                bw.Write(bytes);
                return DeSerialize<T>(ms, encoding);
            }
        }
        #endregion
    }
}
